#include "CAttribute.h"
#include "clcomfuncs.h"

CAttribute::CAttribute(CLComString pathName)
{
	m_pDataFile = NULL;
	CreateAttribute(pathName);
}
void CAttribute::Copy(CAttribute* pdst, const CAttribute* psrc)
{
	if (pdst == psrc)	return;

	pdst->ClearAttributes();

    map<CLComString, ECLCOMVALUE_TYPE>::const_iterator it =
		psrc->m_mapSupportAttributes.begin();
	for (; it != psrc->m_mapSupportAttributes.end(); ++it)
	{
		pdst->RegisterAttribute(it->first, it->second);

        CLComValue item;
		item.SetKey(it->first.GetChars());
		psrc->GetAttribute(item);
		pdst->ModifyAttribute(item);
	}
}

CAttribute::~CAttribute()
{
	Release();
}
void CAttribute::Release()
{
	delete m_pDataFile;
	m_pDataFile = nullptr;
}

int CAttribute::ModifyAttribute(CLComValue& item)
{
	int eRet = ERECORD_RETURN_VALUE_OK;

    ECLCOMVALUE_TYPE valuetype = SupportAttribute(item.GetKey());
	switch (valuetype)
	{
    case ECLCOMVALUE_TYPE_NO:
		eRet = ERECORD_RETURN_VALUE_FALSE;
		break;
    case ECLCOMVALUE_TYPE_INT:
	{
		if (m_pDataFile->GetIntValue(item.GetKey()) == item.GetIntValue())
		{
			eRet = ERECORD_RETURN_VALUE_FALSE;
		}
		m_pDataFile->SetIntValue(item.GetKey(), item.GetIntValue());
	}
	break;
    case ECLCOMVALUE_TYPE_DOUBLE:
	{
        if (CLComFuncs::FloadIsZero(m_pDataFile->GetDoubleValue(item.GetKey()) - item.GetDoubleValue()))
		{
			eRet = ERECORD_RETURN_VALUE_FALSE;
		}
		m_pDataFile->SetDoubleValue(item.GetKey(), item.GetDoubleValue());
	}
	break;
    case ECLCOMVALUE_TYPE_STRING:
	{
		if (m_pDataFile->GetStringValue(item.GetKey()) == item.GetStringValue())
		{
			eRet = ERECORD_RETURN_VALUE_FALSE;
		}
		m_pDataFile->SetStringValue(item.GetKey(), item.GetStringValue());
	}
	break;
    case ECLCOMVALUE_TYPE_POBJ:
	{
		if (m_pDataFile->GetPObject(item.GetKey()) == item.GetPObject())
		{
			eRet = ERECORD_RETURN_VALUE_FALSE;
		}
		m_pDataFile->SetObject(item.GetKey(), item.GetPObjectLen(),	item.GetPObject(), true);
	}
	break;
	default:
		break;
	}
	return eRet;
}

void CAttribute::GetAttributes(map<string, CLComValue>& outAttributes)const
{
    map<CLComString, ECLCOMVALUE_TYPE>::const_iterator it = m_mapSupportAttributes.begin();
	for (; it != m_mapSupportAttributes.end(); ++it)
	{
        CLComValue item;
		item.SetKey(it->first.GetChars());
		GetAttribute(item);
		outAttributes[it->first.GetChars()] = item;
	}
}

int CAttribute::GetAttribute(CLComValue& item)const
{
	return GetAttributeAux(item, m_pDataFile);
}

void CAttribute::ClearAttributes()
{
	m_mapSupportAttributes.clear();
	m_pDataFile->ClearKeys();
}

void CAttribute::LoadFromFile(CLComString fileName)
{
	CDataFile dataFile(fileName);

	CDataFile::Copy(m_pDataFile, &dataFile);
	Update();
}

int CAttribute::GetAttributeAux(CLComValue& item, CDataFile* pDataFile)const
{
    map<CLComString, ECLCOMVALUE_TYPE>::const_iterator it = m_mapSupportAttributes.find(item.GetKey());
	if (it != m_mapSupportAttributes.end())
	{
		switch (it->second)
		{
        case ECLCOMVALUE_TYPE_NO:
			return ERECORD_RETURN_VALUE_FALSE;
			break;
        case ECLCOMVALUE_TYPE_INT:
			item.SetIntValue(pDataFile->GetIntValue(it->first));
			break;
        case ECLCOMVALUE_TYPE_DOUBLE:
			item.SetDoubleValue(pDataFile->GetDoubleValue(it->first));
			break;
        case ECLCOMVALUE_TYPE_STRING:
			item.SetStringValue(pDataFile->GetStringValue(it->first));
			break;
        case ECLCOMVALUE_TYPE_POBJ:
			item.SetObjValue(pDataFile->GetPObject(it->first), pDataFile->GetPObjectLen(it->first));
			break;
		default:
			return ERECORD_RETURN_VALUE_FALSE;
			break;
		}
		return ERECORD_RETURN_VALUE_OK;
	}
	return ERECORD_RETURN_VALUE_FALSE;
}

void CAttribute::RegisterAttribute(CLComString key, ECLCOMVALUE_TYPE type)
{
	m_mapSupportAttributes[key] = type;
}

ECLCOMVALUE_TYPE CAttribute::SupportAttribute(CLComString key)
{
    map<CLComString, ECLCOMVALUE_TYPE>::iterator it = m_mapSupportAttributes.find(key);
	if (it != m_mapSupportAttributes.end())
	{
		return it->second;
	}
    return ECLCOMVALUE_TYPE_NO;
}

void CAttribute::CreateAttribute(CLComString dataFile)
{
	if (!m_pDataFile)
	{
		m_pDataFile = new CDataFile(dataFile);
	}
}

bool CAttribute::GoBack(int nIndex)
{
	if (m_pDataFile)
	{
		return m_pDataFile->GoBack(nIndex);
	}
	return false;
}

bool CAttribute::GoNext(int nIndex)
{
	if (m_pDataFile)
	{
		return m_pDataFile->GoNext(nIndex);
	}
	return false;
}
int CAttribute::BackUp(CRecordItem& recordinfo)
{
	if (m_pDataFile)
	{
		return m_pDataFile->BackUp(recordinfo);
	}
	return -1;
}
void CAttribute::Update()
{
	if (m_pDataFile)
	{
		return m_pDataFile->Update();
	}
}

void CAttribute::ClearBackup()
{
	if (m_pDataFile)
	{
		return m_pDataFile->ClearBackup();
	}
}
void CAttribute::Save2File(FILE* file)
{
	if (m_pDataFile)
	{
		return m_pDataFile->Save2File(file);
	}
}
